﻿using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using RBAC.Domain.Service.Impl;
using RBAC.Domain.Service.Interfae;
using RBAC.Repository;
using RBAC.Repository.Impl;
using RBAC.Repository.Interfae;
using RBAC.Repository.RabbitImpl;
using RBAC.Repository.RabbitInterfae;
using System.Text;
using Traceability.Service.Impl;
using Traceability.Service.Interfae;

namespace RBACDuYaJun.Api.Extensions
{
    public static class ServiceCollectionExtensions
    {
        /// <summary>
        /// this 扩展语法
        /// string 代表被扩展的类型
        /// </summary>
        /// <param name="para">值</param>
        /// <returns></returns>
        public static int ToInt(this string para)
        {
            int result = 0;
            if(int.TryParse(para, out result))//true 类型转换成功
            {
                return result;
            }
            else
            {
                return -9999;
            }
        }
        public static string GetBirthDay(this string idCard)
        {
            return idCard.Substring(6, 8);
        }
        /// <summary>
        /// 注册数据库
        /// </summary>
        /// <param name="services"></param>
        /// <param name="connectionString"></param>
        /// <param name="enableSalog">Sql</param>
        /// <returns></returns>
        public static IServiceCollection AddDbContextService<TDbContext>(this IServiceCollection services,
            string? connectionString,bool enableSalLog) where TDbContext : DbContext
        {
            return services.AddDbContext<TDbContext>(builder =>
            {
                builder.UseSqlServer(connectionString, action =>
                {
                    action.EnableRetryOnFailure(
                        maxRetryCount: 10,
                        maxRetryDelay: TimeSpan.FromSeconds(60),
                        errorNumbersToAdd: null
                        );

                }).EnableSensitiveDataLogging();
                if (enableSalLog)
                {
                    builder.UseLoggerFactory(LoggerFactory.Create(configure =>
                    {
                        configure
                        .AddFilter((category, level) => category == DbLoggerCategory.Database.Command.Name && level == LogLevel.Information)
                        .AddConsole();
                    }));
                }
            });
        }
        /// <summary>
        /// 扩展注入方法
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddService(this IServiceCollection services)
        {
            #region RBAC注入

            //用户服务层注入
            services.AddScoped<IUserService,UserServices>();
            //省份服务层注入
            services.AddScoped<IProvinceService,ProvinceService>();
            //所在市服务层注入
            services.AddScoped<ICityService,CityService>();
            //所在县服务层注入
            services.AddScoped<ICountryService,CountryService>();
            //角色服务层注入
            services.AddScoped<IRoleService,RoleService>();
            //用户与角色服务层注入
            services.AddScoped<IUserRoleService,UserRoleService>();
            //菜单服务层注入
            services.AddScoped<IMenuService, MenuService>();
            //角色与菜单服务层注入
            services.AddScoped<IRoleMenuService, RoleMenuService>();
            //请假服务层注入
            services.AddScoped<ILeaveService, LeaveService>();
            //请假类型服务层注入
            services.AddScoped<ILeaveTypeService, LeaveTypeService>();

            //用户仓储层注入
            services.AddScoped<IUserRepository, UserRepository>();
            //省份仓储层注入
            services.AddScoped<IProvinceRepository, ProvinceRepository>();
            //市仓储层注入
            services.AddScoped<ICityRepository, CityRepository>();
            //县仓储层注入
            services.AddScoped<ICountryRepository, CountryRepository>();
            //角色仓储层注入
            services.AddScoped<IRoleRepository, RoleRepository>();
            //用户与角色仓储层注入
            services.AddScoped<IUserRoleRepository, UserRoleRepository>();
            //菜单仓储层注入
            services.AddScoped<IMenuRepository, MenuRepository>();
            //角色与菜单仓储层注入
            services.AddScoped<IRoleMenuRepository, RoleMenuRepository>();
            //请假仓储层注入
            services.AddScoped<ILeaveRepository, LeaveRepository>();
            //请假类型仓储层注入
            services.AddScoped<ILeaveTypeRepository, LeaveTypeRepository>();

            #endregion

            //商品服务层注入
            services.AddScoped<IGoodsService, GoodsService>();
            //图片服务层注入
            services.AddScoped<IImgsService, ImgSrcService>();
            //溯源服务层注入
            services.AddScoped<ITraceabilitysService, TraceabilitysService>();
            //养殖信息服务层注入
            services.AddScoped<IBreedService, BreedService>();
            //保健信息服务层注入
            services.AddScoped<IHealthService, HealthService>();
            //养殖企业信息服务层注入
            services.AddScoped<IBreedEnterpriseService, BreedEnterpriseService>();
            //屠宰信息服务层注入
            services.AddScoped<ISlaughterService, SlaughterService>();
            //屠宰企业信息服务层注入
            services.AddScoped<ISlPriseService, SlPriseService>();
            //深加工信息服务层注入
            services.AddScoped<IProcessdService, ProcessdService>();
            //原料信息服务层注入
            services.AddScoped<IRawService, RawService>();
            //辅料信息服务层注入
            services.AddScoped<IAuxiliaryService, AuxiliaryService>();
            //添加剂信息服务层注入
            services.AddScoped<IAdditiveService, AdditiveService>();
            //包材信息服务层注入
            services.AddScoped<IPackagingService, PackagingService>();
            //深加工企业信息服务层注入
            services.AddScoped<IDeepEnterprisService, DeepEnterprisService>();


            //商品仓储层注入
            services.AddScoped<IGoodsRepository, GoodsRepository>();
            //图片仓储层注入
            services.AddScoped<IImgRepository, ImgsRepository>();
            //溯源仓储层注入
            services.AddScoped<ITraceabilitysRepository, TraceabilitysRepository>();
            //养殖信息仓储层注入
            services.AddScoped<IBreedRepository, BreedRepository>();
            //保健信息仓储层注入
            services.AddScoped<IHealthRepository, HealthRepository>();
            //养殖企业信息仓储层注入
            services.AddScoped<IBreedEnterpriseRepository, BreedEnterpriseRepository>();
            //屠宰信息仓储层注入
            services.AddScoped<ISlaughterRepository, SlaughterRepository>();
            //屠宰企业信息仓储层注入
            services.AddScoped<ISlPriseRepository, SlPriseRepository>();
            //深加工信息仓储层注入
            services.AddScoped<IProcessdRepository, ProcessdRepository>();
            //原料信息仓储层注入
            services.AddScoped<IRawRepository, RawRepository>();
            //辅料信息仓储层注入
            services.AddScoped<IAuxiliaryRepository, AuxiliaryRepository>();
            //添加剂信息仓储层注入
            services.AddScoped<IAdditiveRepository, AdditiveRepository>();
            //包材信息仓储层注入
            services.AddScoped<IPackagingRepository, PackagingRepository>();
            //深加工企业信息仓储层注入
            services.AddScoped<IDeepEnterprisesRepository, DeepEnterprisesRepository>();


            return services;
        }
        /// <summary>
        /// 注册JWT
        /// </summary>
        /// <param name="collection"></param>
        /// <param name="builder"></param>
        public static void AddJWT(this IServiceCollection collection,WebApplicationBuilder builder)
        {
            builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(options =>
                {
                    //取出秘钥
                    var secretByte = Encoding.UTF8.GetBytes(builder.Configuration["Authentication:SecretKey"]);
                    options.TokenValidationParameters = new TokenValidationParameters()
                    {
                        //验证发布者
                        ValidateIssuer = true,
                        ValidIssuer = builder.Configuration["Authentication:Issuer"],
                        //验证接收者
                        ValidateAudience = true,
                        ValidAudience = builder.Configuration["Authentication:Audience"],
                        //验证是否过期
                        ValidateLifetime = true,
                        //验证私钥
                        IssuerSigningKey = new SymmetricSecurityKey(secretByte)
                    };
                });
        }
    }
}
